package cn.edu.cug.cs.gtl.renders.openinventor.nodes;

import cn.edu.cug.cs.gtl.apis.render.basics.*;
import cn.edu.cug.cs.gtl.apis.render.nodes.Node;
import cn.edu.cug.cs.gtl.apis.render.paths.Path;
import cn.edu.cug.cs.gtl.renders.openinventor.basics.ViewVolumeImpl;
import cn.edu.cug.cs.gtl.renders.openinventor.basics.ViewportRegionImpl;
import com.openinventor.inventor.*;
import com.openinventor.inventor.nodes.SoCamera;
import com.openinventor.inventor.nodes.SoNode;

public class CameraImpl extends NodeImpl implements cn.edu.cug.cs.gtl.apis.render.nodes.Camera{


    public CameraImpl(SoCamera s) {
        super();
        this.nativeObject = s;
    }


    /**
     * Returns the viewport region this camera would use to render into the given viewport region, accounting for cropping.
     *
     * @param region
     * @return
     */
    @Override
    public ViewportRegion getViewportBounds(ViewportRegion region) {
        return new ViewportRegionImpl(
                ((SoCamera)nativeObject).getViewportBounds((SbViewportRegion) region.getNativeObject())
                );
    }

    /**
     * Calls getViewVolume((float)0.0).
     *
     * @return
     */
    @Override
    public ViewVolume getViewVolume() {
        return new ViewVolumeImpl(((SoCamera)nativeObject).getViewVolume());
    }

    /**
     * Returns a view volume object, based on the camera's viewing parameters.
     *
     * @param useAspectRatio
     * @return
     */
    @Override
    public ViewVolume getViewVolume(float useAspectRatio) {
        return new ViewVolumeImpl(((SoCamera)nativeObject).getViewVolume(useAspectRatio));
    }

    /**
     * Computes a view volume from the given parameters.
     *
     * @param aspectRatio
     * @param nearDist
     * @param farDist
     * @param position
     * @param rotation
     * @return
     */
    @Override
    public ViewVolume getViewVolume(float aspectRatio, float nearDist, float farDist, Vec3f position, Rotation rotation) {
        return new ViewVolumeImpl(((SoCamera)nativeObject).getViewVolume(aspectRatio,nearDist,farDist,
                (SbVec3f) position.getNativeObject(),
                (SbRotation) rotation.getNativeObject()
                ));
    }

    /**
     * Scales the height of the camera.
     *
     * @param scaleFactor
     */
    @Override
    public void scaleHeight(float scaleFactor) {
        ((SoCamera)nativeObject).scaleHeight(scaleFactor);
    }

    /**
     * Calls viewAll(sceneRoot, vpRegion, (float)1.0).
     *
     * @param sceneRoot
     * @param vpRegion
     */
    @Override
    public void viewAll(Node sceneRoot, ViewportRegion vpRegion) {
        ((SoCamera)nativeObject).viewAll(
                (SoNode) sceneRoot.getNativeObject(),
                (SbViewportRegion) vpRegion.getNativeObject()
        );
    }

    /**
     * Sets the camera to view the scene rooted by the given node.
     *
     * @param sceneRoot
     * @param vpRegion
     * @param slack
     */
    @Override
    public void viewAll(Node sceneRoot, ViewportRegion vpRegion, float slack) {
        ((SoCamera)nativeObject).viewAll(
                (SoNode) sceneRoot.getNativeObject(),
                (SbViewportRegion) vpRegion.getNativeObject(),
                slack
        );
    }

    /**
     * Sets the camera to view the region defined by the given bounding box.
     *
     * @param bbox
     * @param vpRegion
     */
    @Override
    public void viewAll(Box3f bbox, ViewportRegion vpRegion) {
        ((SoCamera)nativeObject).viewAll(
                (SbBox3f) bbox.getNativeObject(),
                (SbViewportRegion) vpRegion.getNativeObject()
        );
    }

    /**
     * Calls viewAll(path, vpRegion, (float)1.0).
     *
     * @param path
     * @param vpRegion
     */
    @Override
    public void viewAll(Path path, ViewportRegion vpRegion) {
        ((SoCamera)nativeObject).viewAll(
                (SoPath) path.getNativeObject(),
                (SbViewportRegion) vpRegion.getNativeObject()
        );
    }

    /**
     * Sets the camera to view the scene defined by the given path.
     *
     * @param path
     * @param vpRegion
     * @param slack
     */
    @Override
    public void viewAll(Path path, ViewportRegion vpRegion, float slack) {
        ((SoCamera)nativeObject).viewAll(
                (SoPath) path.getNativeObject(),
                (SbViewportRegion) vpRegion.getNativeObject(),
                slack
        );
    }
}
